package com.alterzhang.userservice.proxy.zshproxy;

import entity.Person;

import javax.tools.JavaCompiler;
import javax.tools.StandardJavaFileManager;
import javax.tools.ToolProvider;
import java.io.File;
import java.io.FileWriter;
import java.lang.reflect.Constructor;
import java.lang.reflect.Method;

public class zshproxy {


    private static final String ln = "\r\n";


    /**
     * @param loader
     * @param interfaces
     * @param h
     * @return 创建一个代理对象
     */
    public static Object newProxyInstance(zshClassLoader loader, Class<?>[] interfaces, zshInvocationHandler h) {

        //生成.java 文件
        String source = generateStr(interfaces[0]);
        String filePath = zshproxy.class.getResource("").getPath();
        File file = new File(filePath + "$Proxy0.java");

        try {
            FileWriter fileWriter = new FileWriter(file);
            fileWriter.write(source);
            fileWriter.flush();
            fileWriter.close();
            //编译文件
            JavaCompiler compiler = ToolProvider.getSystemJavaCompiler();
            StandardJavaFileManager fileManager = compiler.getStandardFileManager(null, null, null);
            Iterable iterable = fileManager.getJavaFileObjects(file);
            JavaCompiler.CompilationTask compilationTask = compiler.getTask(null, fileManager, null, null, null, iterable);
            compilationTask.call();
            fileManager.close();
            Class clazz = loader.findClass("$Proxy0");
            //读到内存中后删除源文件
/*
            file.delete();
*/
            Constructor c = clazz.getConstructor(zshInvocationHandler.class);
            return c.newInstance(h);
        } catch (Exception e) {
            e.printStackTrace();
        }
        //生成.class文件
        //加载到内存
        //返回被代理的代理对象

        return null;
    }


    /**
     * @param interfaces
     * @return 生成 .Java文件
     */
    private static String generateStr(Class<?> interfaces) {

        StringBuffer sb = new StringBuffer();
        sb.append("package com.alterzhang.userservice.proxy.zshproxy;" + ln);

        sb.append("import java.lang.reflect.Method;" + ln);
        sb.append("public class $Proxy0  implements " + interfaces.getName() + "{" + ln);


        sb.append("zshInvocationHandler  h;" + ln);

        sb.append("public $Proxy0 (zshInvocationHandler h){" + ln);
        sb.append("this.h=h;" + ln);
        sb.append("}" + ln);


        for (Method m : interfaces.getMethods()) {
            System.out.println(m.getReturnType().getName() + "===" + m.getReturnType());

            sb.append("public " + m.getReturnType().getName() + " " + m.getName() + "() throws Throwable{" + ln);

            sb.append("Method m= " + interfaces.getName() + ".class.getMethod(\"" + m.getName() + "\",new Class[]{});" + ln);

            sb.append("this.h.invoke(this,m,null);");
            sb.append("}" + ln);

        }


        sb.append("}");

        return sb.toString();
    }

    public static void main(String[] args) {


        String sb = generateStr(Person.class);

        System.out.println(sb.toString());
    }
}
